// *********************************************************
//      Copyright (c) Kosta Gaitanis
//      All rights reserved
//
//      k.gaitanis@gmail.com
//
// *********************************************************

#ifndef GLPIPELINE_H
#define GLPIPELINE_H

#include <QGLShaderProgram>
#include <QGLBuffer>
#include <QGLFramebufferObject>
#include <QObject>
#include <QGLWidget>
//#include <QtOpenGL/qglfunctions.h>

///
/// \brief The GLPipeline class
///
class GLPipeline : public QObject
{
    Q_OBJECT
public:
    GLPipeline(QObject *parent = 0);
    virtual ~GLPipeline();

    virtual QVariant getPipelineParameter(const QString& name) const;

signals:
    void requestPaintItems();
    void updateGL();

public slots:
    virtual void initialize();
    virtual void render();
    virtual void resize(int w, int h);
    virtual void setPipelineParameter(const QString& name, const QVariant& value);

};

//////////////////////////////////////
/// \brief The FBOPipeline class
///
class FBOPipeline : public GLPipeline
{
    Q_OBJECT
public:
    FBOPipeline(QObject *parent = 0);
    virtual ~FBOPipeline();

    QSize getGLSize() const;
    QSize getRenderResolution() const;
    virtual QVariant getPipelineParameter(const QString &name) const;

    // parameters
    void setGamma(double gamma);
    void setRenderGlow(bool render);
    void setGlowTextureSize(QSize size);
    void setBlurSamples(int samples);
    void setRenderSize(QSize size);

public slots:
    virtual void initialize();
    virtual void render();
    virtual void resize(int w, int h);
    virtual void setPipelineParameter(const QString &name, const QVariant &value);

private:
    void paintTextureQuad(GLuint texture);
    void createShaders();
    void createTextures();

    void renderScene();
    void renderGlow();

    QGLShaderProgram *m_shaderProgram;
    QGLShaderProgram *m_finalRenderProgram;
    QGLShaderProgram *m_blurProgram;

    double m_gamma;
    int m_blurSamples;

    GLuint m_FBO;
    GLuint m_renderTexture;
    GLuint m_depthTexture;
    GLuint m_glowTexture;
    GLuint m_glowHBlurTexture;

    QSize m_glSize;
    QSize m_renderTextureSize;
    QSize m_glowTextureSize;

    bool m_renderGlow;
};

#endif // GLPIPELINE_H
